package com.middleware.proxy;

import com.middleware.annotations.OrmDelete;
import com.middleware.annotations.OrmInsert;
import com.middleware.annotations.OrmSelect;
import com.middleware.annotations.OrmUpdate;
import com.middleware.connect.DbConnection;
import com.middleware.executor.DatabaseExecutor;
import com.middleware.mappers.ExecutorResultMapper;
import com.middleware.parse.ParsedSql;
import com.middleware.parse.SqlParameterParser;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;


// 真正的调用处理器
public class DaoInvocationHandler implements InvocationHandler {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Connection conn = DbConnection.getConnection();

        // 1. 解析方法上的注解获取SQL
        String sql = parseSqlFromAnnotation(method);
        if (sql == null) {
            throw new RuntimeException("方法 " + method.getName() + " 没有配置SQL注解");
        }
            
        // 2. 处理参数替换（将 #{id} 替换为 ?）
        ParsedSql parsedSql = SqlParameterParser.parseParameters(sql, args, method.getParameters());

        // 3. 根据注解类型执行相应的数据库操作
        if (method.isAnnotationPresent(OrmSelect.class)) {

            ResultSet resultSet = DatabaseExecutor.executeQuery(parsedSql,conn);
            if(resultSet.isClosed()){
                throw new SQLException("ResultSet is already closed");
            }
            try {
                return ExecutorResultMapper.map(resultSet, method.getReturnType(), method.getGenericReturnType());
            }finally {
                if(!resultSet.isClosed()){
                    resultSet.close();
                }
                if(!conn.isClosed()){
                    conn.close();
                }
            }
        } else if (method.isAnnotationPresent(OrmInsert.class) ||
                method.isAnnotationPresent(OrmUpdate.class) ||
                method.isAnnotationPresent(OrmDelete.class)) {
            return DatabaseExecutor.executeUpdate(parsedSql);
        }
            
        throw new RuntimeException("不支持的SQL操作类型");
    }

    private String parseSqlFromAnnotation(Method method) {
        if (method.isAnnotationPresent(OrmSelect.class)) {
            return method.getAnnotation(OrmSelect.class).value();
        } else if (method.isAnnotationPresent(OrmInsert.class)) {
            return method.getAnnotation(OrmInsert.class).value();
        } else if (method.isAnnotationPresent(OrmUpdate.class)) {
            return method.getAnnotation(OrmUpdate.class).value();
        } else if (method.isAnnotationPresent(OrmDelete.class)) {
            return method.getAnnotation(OrmDelete.class).value();
        }
        return null;
    }
}
